TagsNote: This functionality is not yet implemented. This document describes how it's planned. Tags are defined as subclasses of xjavadoc.DefaultXTag. If you want to define a class-level tag that can be used like this... /** * @sql.table name="Customers" */ ...it should be done as folows: /** * @xdoclet.tag * name="sql.table" * class="true" * inherit="false" */ public abstract class SqlTableTag extends xjavadoc.DefaultXTag { /** * @xdoclet.tag-attribute name="name" */ public abstract String getName(); } I'll explain further down why the class should be abstract. Defining a tag with a standard java class this way will allow us to do three important things:
Generate tag documentationThis will be done by the xtags plugin. It will generate a simple object model of the tags and use Velocity to render a document. The plugin will have a built-in Velocity template that can generate xdoc documents for further processing with Maven but it's possible to supply a custom template in order to generate tag documents in other formats. Tag validationThere are several ways to validate tags:
TagMetaData APIXJavadoc will be augmented with an API to access meta-data about various @tags. This API will provide information about where a tag is appliccable, valid tag attributes, whether they are mandatory, description and so on. Each @tag will have a separate XML descriptor similar to the current xtags.xml. For a tag named @foo.bar, there will be a foo.bar.tag.xml descriptor. The TagMetaData API implementation will parse these descriptors and make the information available via first-class java objects. This is very useful for IDE plugins that want to implement code-completion for @tags. The XDoclet plugin developer can choose whether she wants to write the *.tag.xml descriptor by hand or have it generated from a tagged DefaultXTag subclass. The XDoclet SDK will provide a special XDoclet plugin generate these files. How are the tags instantiated?It's possible to preconfigure xjavadoc to instantiate a particular XTag class when it encounters a particular tag name. In order to be able to do that, the tag name must be mapped to the class of the tag object it is supposed to instantiate. This is done by calling the xjavadoc.XTagFactory.registerTagClass(java.lang.String, java.lang.Class) method. This should be done before parsing of the sources. -And what's a more natural place to define this mapping than in xdoclet-plugin.xml! This means that when XDoclet starts up, xdoclet.PluginFactory will do this registration. The xdoclet-plugin.xml is generated from Plugin classes with @xdoclet.plugin tags. We'll just improve the plugin plugin a bit so that it can take into account the XTag classes with @xdoclet.tag tags too. IDE code completionIn order to support code completion in IDE plugins for XDoclet, we need to provide some metadata about the tags and where they fit in. Provided that the IDE plugin actually knows enough about the code it's editing (let's hope they do!), they could benefit from a little API extension in xjavadoc. (This might actually be useful for xjavadoc's validation too!). public interface XProgramElement { public Collection getLegalTags(); } public interface XTag { public Collection getLegalAttributes(); } These interfaces are defined by XJavaDoc, and have to be implemented by each IDE plugin provider. XClass defines methods that provide metadata about the class being edited. How it's implemented doesn't matter, but it has to be done by the IDE plugin provider, since the edited classes aren't compiled, and it's only the IDE that can possibly provide the required metadata. xjavadoc.SourceClass can't be used, since it requires the class to be perfect, which is probably not the case in an IDE, especially if there are a few syntax errors. But modern IDEs are smart, and they'll be able to provide a decent implementation, probably by wrapping some of the classes in the IDE core. Then, when the user moves around in the source and types a @ the IDE will pop up a list of legal tags. When the tag is typed and space is hit, the IDE can pop up a list of legal attributes for that tag. What's the best way to keep this info? The XTag implementation classes that are partly hand coded, partly generated is perfect for the tag attributes. But how about the XClass? It could be done using the XTag's built-in validation logic in a slightly different manner. Just try to set each registered tag programmatically. If a ValidationException is thrown, the tag is not legal. Tag dependenciesSome tags don't make sense unless an other tag is present. For example, @ejb.ejb-ref makes no sense unless there is a @ejb.bean tag somewhere. We need to define tag dependencies somehow. Then part of the validation logic should check that all defined dependencies are satisfied in every source file. This validation should be done entirely outside xdoclet, and only occur in the xjavadoc framework. How to define these dependencies is still not decided, but we might do it with tags too: +------------------------------------------------------------------- /** * @xdoclet.tag * name="ejb.ejb-ref" * depends="ejb.bean" * +------------------------------------------------------------------- ConclusionDefining tags as classes will keep docs uptodate with the code and it provides a flexible validation mechanism and opens for code completion in IDEs |